/**
 * 
 * The ClientConnectionManager is responsible for the connection from the application (as a client) to another (which acts as a server).
 * 
 * Author: Matthias Van Eeghem <matthias@van-eeghem.com>
 * All rights reserved.
 * 
 */

package com.bomberman.connection;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.SocketException;
import java.net.UnknownHostException;

import com.bomberman.Main;
import com.bomberman.core.GameState;
import com.bomberman.core.GameState.eState;

public class ClientConnectionManager 
{
	// Holds the socket for the connection
	private Socket socket = null;
	// The PrintWriter to send data from the client to the server
    private PrintWriter out = null;
    // The BufferedReader to receive data from the server
    private BufferedReader in = null;
    // Holds the above-laying connection manager object
	private volatile ConnectionManager connectionManager;
	
    /**
     * The constructor for the ClientConnectionManager. Connects the client to the server.
     * 
     * @param ip The ip to connect to
     * @param port The port to connect to
     * @throws IOException
     * @throws ClassNotFoundException
     */
	public ClientConnectionManager(ConnectionManager connectionManager, String ip, int port) throws IOException, ClassNotFoundException
	{
		this.connectionManager = connectionManager;
		
	    try 
	    {
	    	socket = new Socket(ip, port);
	        out = new PrintWriter(socket.getOutputStream(), true);
	        in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
	    }
	    
	    // Couldn't connect to host
	    catch (UnknownHostException e)
	    {
	    	System.err.println("Don't know about host: " + ip + ":" + port);
	        System.exit(1);
	    }
	    
	    // Couldn't get any IO from the connection
	    catch (IOException e)
	    {
	    	System.err.println("Couldn't get I/O for the connection to: " + ip + ":" + port);
	        System.exit(1);
	    }
	    
	    // We're connected!
	    GameState.setGameState(eState.GameStateConnected);
	}
	
	/**
	 * Makes the client read data from the server.
	 * 
	 * @throws IOException
	 */
	public void run() throws IOException
	{
		// Read from the std in
	    BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in));
	    
	    try
	    {
		    String data = null;
		    
		    // Make a CommunicationProtocol object
	    	CommunicationProtocol protocol = new CommunicationProtocol(connectionManager);
	    	
	    	sendData(Main.playerName);
	    	
	    	// Keep reading data from the server
		    while ((data = in.readLine()) != null) 
			{
		    	// Handle the data we received
				protocol.handleData(data);
			}
	    }
	    
	    catch (SocketException e)
	    {
	    	// Close all streams and sockets
		    out.close();
		    in.close();
		    stdIn.close();
		    socket.close();
	    }
	}
	
	/**
	 * Sends data from the client to the server
	 * 
	 * @param data
	 */
	public void sendData(String data)
	{
		out.println(data);
		out.flush();
	}
}
